<?php

    require(dirname(__FILE__).'/../globals.inc');

    $mikron->Page->StartBody();
    require_once(dirname(__FILE__).'/menu.inc');

    foreach($mikron->Site->Schemas() as $schema)
    {
       $mikron->Schema->Add($schema['file'], $schema['name']) ;
    }
    foreach($mikron->Schema->Schemas() as $scheme)
    {
        $current_schema_file = $scheme->file();
        $current_schema_name = $scheme->name();
        break;
    }
    if(isset($_GET['editschemafile']))
    {
        $file = $_GET['editschemafile'];
        $scheme = $mikron->Schema->Schemas($file);
        if(!is_null($scheme))
        {
            $current_schema_file = $scheme->file();
            $current_schema_name = $scheme->name();
        }
    }

?>

<div style="padding-left: 1em; ">
    <h2><?php echo $current_schema_name; ?>, редактирование:</h2>
    <form s tyle="display: none;" id="mikronForm" action="<?php echo $_SERVER['SCRIPT_NAME']; ?>?save_schema" method="POST">
        <input name="editschemafile" type="hidden" value="<?php echo $current_schema_file;?>">
        {{superliteral}}<textarea name="newschema" cols="196" rows="32"><?php echo htmlspecialchars(file_get_contents($current_schema_file)); ?></textarea>{{/superliteral}}
        <br /><input type="submit" value="Сохранить схему" />
    </form>

<?php

    // список аттрибутов справочника
    $a_enum_attributes = Array("name" => true, "description" => true, "value" => true);
    // список аттрибутов описания сущности
    $a_entity_attributes = Array('description' => false, 'inmenu' => false, 'url' => false, 'tostring' => false, 'searchresult' => false, 'displayname' => false);
    // список нодовых свойств сущности
    $a_entity_nodes = Array('template' => false);
    // список аттрибутов поля сущности
    $a_fields = Array("type" => true, "hidden" => false,
                      "forsearch" => false, "description" => true, "help" => false,
                      'unique' => false, 'default' => false, 'childattribute' => false,
                      'validator' => false, 'group' => false, 'allownull' => false);

    if(isset($_REQUEST['ok']))
    {
        $ok = $_REQUEST['ok'];
        switch($ok)
        {
            case "saved":
                ?><p>Схема успешно сохранена.</p><?php
                break;
            default:
                ?><p>Схема успешно обновлена.</p><?php
                break;
        }
    }

    // сохранение изменений схемы
    if(isset($_REQUEST['save_schema']) && isset($_REQUEST['editschemafile']))
    {
        $edited_filename = $_REQUEST['editschemafile'];
        try
        {
            $schema = $_REQUEST['newschema'];
            /**
            * Удаляем возможный мусор от смарти
            */
            if(substr($schema, 0, 11) == '{{literal}}')
            {
                $schema = substr($schema,11);
            }
            if(substr($schema, -12, 12) == '{{/literal}}')
            {
                $schema = substr($schema, 0, strlen($schema) - 12);
            }
            $file = $edited_filename;
            if(get_magic_quotes_gpc())
            {
                $schema = stripslashes($schema);
            }
            file_put_contents($file, $schema);
            $mikron->Tools->GoToPage($_SERVER['SCRIPT_NAME']."?ok=saved&editschemafile=".$edited_filename);
        }
        catch(Exception $ex)
        {
            CriticalError("Ошибка сохранения схемы. ".$ex->GetMessage());
        }
    }

    $shemeEnums = Array();
    $schemeEntities = Array();

    foreach($mikron->Schema->Schemas() as $v_schema)
    {
        $v_schemafile = $v_schema->file();
        
        if(!file_exists($v_schemafile))
        {
            CriticalError("Не найден файл схемы $v_schemafile", null, true);
        }
        $dom = new DOMDocument();
        $dom->load($v_schemafile);
        $datatag = $dom->getElementsByTagName('scheme');

        if($datatag->length == 0)
        {
            CriticalError("Не удалось разобрать файл схемы. Неверная схема.", null, true);
        }

        foreach($datatag as $data)
        {
            // разбор справочников
            $enums = $dom->getElementsByTagName('enum');
            foreach($enums as $enum)
            {
                if($enum->hasAttribute('name'))
                {
                    $name = $enum->getAttribute('name');
                    $description = null;
                    if($enum->hasAttribute('description'))
                    {
                        $description = $enum->getAttribute('description');
                    }
                    $newenum = new sheme_enum($name, $description);
                    $elements = $enum->getElementsByTagName('element');
                    foreach($elements as $element)
                    {
                        if($element->hasAttribute('name') && $element->hasAttribute('value'))
                        {
                            $ename = $element->getAttribute('name');
                            $evalue = $element->getAttribute('value');
                            if(!is_numeric($evalue))
                            {
                                throw new Exception("Энумератор $name имеет ошибку в элементе $ename. Свойство value должно быть числом.");
                            }
                            $edescription = null;
                            if($element->hasAttribute('description'))
                            {
                                $edescription = $element->getAttribute('description');
                            }
                            $enumitem = new enum_item($ename, $evalue, $edescription);
                            $newenum->items[] = $enumitem;
                        }
                    }
                    $shemeEnums[$newenum->name] = $newenum;
                }
            }

            // разбор сущностей
            $entities = $dom->getElementsByTagName('entity');
            $i = 0;
            foreach($entities as $entity)
            {
                $entity_name_value = '';  
                reset($a_entity_attributes);
                /* Вычитка имени сущности */
                if($entity->hasAttribute('name'))
                {
                    $entity_name_value = $entity->getAttribute('name');
                }
                /*Создание объекта описания*/
                if(array_key_exists($entity_name_value, $schemeEntities))
                {
                    $newentity = $schemeEntities[$entity_name_value];
                }
                else
                {
                    $newentity = new sheme_entity($entity_name_value);
                    $schemeEntities[$entity_name_value] = $newentity;
                }

                // аттрибуты сущности
                foreach($a_entity_attributes as $attribute_name => $required_attribute)
                {
                    // if($i++>250)die("recursive call $i");
                    $value = null;
                    if($entity->hasAttribute($attribute_name))
                    {
                        if(!is_null($value = $entity->getAttribute($attribute_name)))
                        {
                            $newentity->$attribute_name = $value;
                        }
                    }
                    elseif($required_attribute)
                    {
                            CriticalError("У сущности `$entity_name_value` отсутствует обязательный аттрибут `$attribute_name`.", null, true);
                    }
                }

                // нодовые аттрибуты сущности
                reset($a_entity_nodes);
                foreach($a_entity_nodes as $attribute_name => $required_attribute)
                {
                    $ts = $entity->getElementsByTagName($attribute_name);
                    if($ts->length > 0)
                    {
                        $attr = & $newentity->$attribute_name;
                        foreach($ts as $value)
                        {
                            $cond = null;
                            $for = null;
                            if($value->hasAttribute('condition'))
                            {
                                $cond = $value->getAttribute('condition');
                            }
                            if($value->hasAttribute('for'))
                            {
                                $for = $value->getAttribute('for');
                            }
                            $attr[] = Array('for'=>$for, 'condition'=>$cond, 'template'=>$value->nodeValue);
                        }

                        $newentity->$attribute_name = $attr;
                    }
                    elseif($required_attribute)
                    {
                        CriticalError("У сущности `$entity_name_value` отсутствует обязательный аттрибут `$attribute_name`.", null, true);
                    }
                }

                // поля
                $default_field = new entity_field();
                $fields_tag = $entity->getElementsByTagName('field');
                foreach($fields_tag as $field)
                {
                    reset($a_fields);
                    $attribute_name_value = $field->getAttribute('name');
                    if(!array_key_exists($attribute_name_value, $newentity->fields))
                    {
                        $newentity->fields[$attribute_name_value] = new entity_field(Array('name' => $attribute_name_value));
                    }
                    foreach($a_fields as $attribute_name => $required_attribute)
                    {
                        $value = $default_field->$attribute_name;
                        if($field->hasAttribute($attribute_name))
                        {
                            $value = $field->getAttribute($attribute_name);
                        }
                        elseif($required_attribute)
                        {
                            CriticalError("У сущности `$name` у поля `$attribute_name_value` отсутствует обязательный аттрибут `$attribute_name`.", null, true);
                        }
                        $newentity->fields[$attribute_name_value]->SetAttributeValue($attribute_name, $value);
                    }
                }
                
                // JS-валидатор
                /*
                $jsvalidators_tag = $entity->getElementsByTagName('jsvalidator');
                foreach($jsvalidators_tag as $jsvalidator)
                {
                    // JS-фильтры
                    $jsfilters = $jsvalidator->getElementsByTagName('jsfilter');
                    {
                        $validator = new js_validator_schemaclass();
                        $ifor = Array();
                        foreach($jsfilters as $jsfilter)
                        {
                            if($jsfilter->hasAttribute("for") && $jsfilter->hasAttribute("condition") && $jsfilter->hasAttribute("invalidmethod"))
                            {
                                $for = $jsfilter->getAttribute("for");
                                if(!array_key_exists($for, $ifor))
                                {
                                    $ifor[$for] = 0;
                                }
                                $ifor[$for]++;
                                if(!array_key_exists($for, $newentity->fields))
                                {
                                    throw new Exception("У сущности ".$newentity->name." нет поля с именем «".$for."» для применения валидатора.");
                                }
                                $filterid = $newentity->name.":".$for.":".$ifor[$for];
                                $condition = $jsfilter->getAttribute("condition");
                                $invalidmethod = $jsfilter->getAttribute("invalidmethod");
                                $filter = new js_filter_schemaclass($filterid, $condition, $invalidmethod);
                                $validator->filters[] = $filter;
                            }
                        }
                        $newentity->fields[$for]->validator = $validator;
                        // print_r($newentity->fields[$for]);
                    }
                }*/
  
                /* 
                // аттрибуты полей сущности
                $childs_tag = $entity->getElementsByTagName('child');
                foreach($childs_tag as $child)
                {
                    reset($a_fields);
                    $newchild = new entity_field();
                    $attribute_name_value = '';
                    foreach($a_fields as $attribute_name => $required_attribute)
                    {
                        $value = $newchild->$attribute_name;
                        if($child->hasAttribute($attribute_name))
                        {
                            $value = $child->getAttribute($attribute_name);
                            if($attribute_name == 'name')
                            {
                                $attribute_name_value = $value;
                            }
                        }
                        elseif($required_attribute)
                        {
                                CriticalError("У сущности `$name` у child-аттрибута `$attribute_name_value` отсутствует обязательный аттрибут `$attribute_name`.", null, true);
                        }
                        $newchild->$attribute_name = $value;
                    }
                    $newentity->childs[] = $newchild;
                }
                */

                /*if(array_key_exists($newentity->name, $schemeEntities))
                {
                    $inscheme = $schemeEntities[$newentity->name];
                    if(($inscheme->description != $newentity->description) && (!is_null($newentity->description))){$inscheme->description = $newentity->description;}
                    if(($inscheme->inmenu != $newentity->inmenu) && (!is_null($newentity->inmenu))){$inscheme->inmenu = $newentity->inmenu;}
                    if(($inscheme->displayname != $newentity->displayname) && (!is_null($newentity->displayname))){$inscheme->displayname = $newentity->displayname;}
                    foreach($newentity->fields as $key => $field)
                    {
                        $inscheme->fields[$key] = $field;
                    }
                }
                else
                {
                    $schemeEntities[$newentity->name] = $newentity;
                }*/
                //$schemeEntities[$newentity->name] = $newentity;
            }
        }
    }

    /*
    echo '<pre>';
    $user = $schemeEntities['T_USER'];
    print_r(array_keys($user->fields));
    exit;
*/

    if(isset($_REQUEST['entity_field_modified']))
    {
        checkFieldModifiers();
    }
    
    function checkFieldModifiers()
    {
        $entity_field_modified = $_REQUEST['entity_field_modified'];
        if(!array_key_exists("entity_name", $entity_field_modified))
        {
            return false;
        }
        if(!array_key_exists("name", $entity_field_modified))
        {
            return false;
        }
        echo "<pre>";
        print_r($entity_field_modified);        
        echo "</pre>";
        return true;
    }

    // Обновление схемы
    if(isset($_REQUEST['update_shema']))
    {
        try
        {

             @mysql_query("CREATE TABLE IF NOT EXISTS `ENUMS` (
              `id` int(11) unsigned NOT NULL auto_increment,
              `name` varchar(64) NOT NULL default '',
              `value` int(11) NOT NULL default '0',
              `description` varbinary(250) default NULL,
              `parent` int(11) NOT NULL default '0',
              PRIMARY KEY  (`id`)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;") or Exception2("Ошибка создания таблицы энумераторов: ".mysql_error());

            @mysql_query("CREATE TABLE IF NOT EXISTS `ENTITIES` (
              `id` int(10) unsigned NOT NULL auto_increment,
              `name` varchar(64) NOT NULL default '',
              `title` varchar(64) NOT NULL,
              `displayname` varchar(255),
              `tostringformat` text NULL,
              `searchresultformat` text NULL,
              `inmenu` varchar(128) NULL default 0,
              `url` varchar(250) NULL default '',
              PRIMARY KEY  (`id`)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;") or Exception2("Ошибка создания таблицы сущностей: ".mysql_error());

            @mysql_query("ALTER TABLE ENTITIES ADD `displayname` varchar(255)");

            // Стартуем транзакцию
            $mikron->Queries->StartTransaction();

            $mikron->Enumerators->clear();
            // перебираем справочники
            foreach($shemeEnums as $e)
            {
                $name = $e->name;
                $description = $e->description;
                // добавляем новый справочник
                $parent = $mikron->Enumerators->add($name, $description);
                foreach($e->items as $enumitem)
                {
                    $ename = $enumitem->name;
                    $evalue = $enumitem->value;
                    $edescription = $enumitem->description;
                    // добавляем элемент для справочника
                    // echo "<li>ADD ENUM ($ename, $edescription, $evalue, $parent)";
                    $mikron->Enumerators->add($ename, $edescription, $evalue, $parent);
                }
            }
  
            $mikron->EntityManager->clear();
            // Добавление сущностей
            foreach($schemeEntities as $ent)
            {
                $mikron->EntityManager->add($ent, $schemeEntities, $shemeEnums);
            }
            $mikron->EntityManager->UpdateEntitiesList();
            $mikron->Queries->CommitTransaction();
            header('Location: '.$_SERVER['SCRIPT_NAME']."?ok&editschemafile=$current_schema_file");
            exit;
        }
        catch(Exception $ex)
        {
            $mikron->Queries->RollbackTransaction();
            CriticalError('Ошибка в файле '.__FILE__.' в строке '.__LINE__.', '.$ex->getMessage());
        }
    }
    else
    {
        ?>
            <p>
            <a onclick="return confirm('Обновить схему сайта?');" href="?update_shema&editschemafile=<?php echo $current_schema_file; ?>">Обновить схему</a>
            </p>
            <script type="text/javascript">
                var prevobject = null;
                var prevobject2 = null;
                function showeditor(object)
                {
                    entityfieldform.style.display = 'none';
                    if(prevobject != null)
                    {
                        prevobject.style.display = 'none';
                    }
                    if(object != null)
                    {
                        object.style.display = '';
                    }
                    prevobject = object;
                }
                function showfieldeditor(entity, name, description, type, help, hidden, size, forsearch)
                {
                    entityfieldform.style.display = '';
                    var _name = document.getElementsByName('entity_field_modified[entity_name]');
                    _name = _name[0];
                    _name.value = entity;
                    if(name == null)
                    {
                        name = '';
                        description = '';
                        type = 'varchar';
                        help = '';
                        hidden = '';
                        size = '250';
                    }
                    var _field = null;
                    _field = document.getElementsByName("entity_field_modified[name]");
                    _field[0].value = name;
                    _field = document.getElementsByName("entity_field_modified[description]");
                    _field[0].value = description;
                    _field = document.getElementsByName("entity_field_modified[type]");
                    _field[0].value = type;
                    _field = document.getElementsByName("entity_field_modified[help]");
                    _field[0].value = help;
                    _field = document.getElementsByName("entity_field_modified[hidden]");
                    _field[0].checked = hidden;
                    _field = document.getElementsByName("entity_field_modified[forsearch]");
                    _field[0].checked = forsearch;
                    _field = document.getElementsByName("entity_field_modified[size]");
                    _field[0].value = size;
                }
                function AddEntityField(entityname)
                {
                    showeditor2(null);
                }
            </script>
            <table cellspacing="0" cellpadding="0">
            <tr>
            <td valign="top" nowrap="nowrap">
                <h3 style="margin: 0;">Схема</h3>
                <ul>
                    <li>Сущности
                        <ul>
                        <?php
                        foreach($schemeEntities as $e)
                        {
                            $ename = $e->name;
                            $edescription = $e->description;
                            ?><li><a href="#" onclick="showeditor(<?php echo $ename; ?>); return false;">
                            <?php echo $ename; ?></a><?php echo " ($edescription)"; ?></li><?php
                        }
                        ?>
                        </ul>
                    </li>
                    <li>Справочники
                        <ul>
                        <?php
                        foreach($shemeEnums as $e)
                        {
                            $ename = $e->name;
                            $edescription = $e->description;
                            ?><li><a href="#" onclick="showeditor(<?php echo $ename; ?>); return false;"><?php echo $ename; ?></a><?php echo " ($edescription)"; ?></li><?php
                        }
                        ?>
                        </ul>
                    </li>
                </ul>
            </td>
            <td style="padding: 2em; padding-top: 0em; ">&nbsp;</td>
            <td valign="top">
                <?php
                foreach($schemeEntities as $e)
                {
                    ?>
                    <div id="<?php echo $e->name; ?>" class="entity_editor" style="display: none;">
                        <p><h3>Просмотр сущности <?php echo $e->name; ?>:</h3></p>
                        <table>
                        <tr><td>Название:</td><td><input size="32" value="<?php echo $e->name; ?>"></td></tr>
                        <tr><td>Описание:</td><td><input size="32" value="<?php echo $e->description; ?>"></td></tr>
                        <tr>
                            <td valign="top">Поля:</td>
                            <td>
                                <?php
                                foreach($e->fields as $field)
                                {
                                    $fname = $e->name.$field->name;
                                    ?><a href="#" onclick="showfieldeditor('<?php echo $e->name; ?>',
                                    '<?php echo $field->name; ?>',
                                    '<?php echo $field->description; ?>',
                                    '<?php echo getbasetype($field->type); ?>',
                                    '<?php echo $field->help; ?>',
                                    '<?php echo $field->hidden; ?>',
                                    '<?php echo getbaselength($field->type); ?>',
                                    '<?php echo $field->forsearch; ?>'
                                    ); return false;"><?php echo $field->name; ?></a>, <?php
                                }
                                ?>
                                <a href="#" onclick="showfieldeditor('<?php echo $e->name; ?>', null, null, null, null, null, null); return false;">+</a>
                            </td>
                        </tr>
                        </table>
                    </div>
                    <?php   
                }
                ?>

                <form id="editentityfield" method="POST" action="?entity_field_modified">
                    <input type="hidden" name="entity_field_modified[entity_name]" value="">
                    <blockquote>
                        <table id="entityfieldform" style="display: none;">
                        <tr><td>Имя:<td><input name="entity_field_modified[name]" size="32" value=""></td>
                        <tr><td>Описание:<td><input name="entity_field_modified[description]" size="32" value=""></td>
                        <tr><td>Тип:<td><select name="entity_field_modified[type]">
                        <option value=""></option>
                        <optgroup LABEL="Базовые типы">
                            <option value="varchar">varchar</option>
                            <option value="text">text</option>
                            <option value="html">html</option>
                            <option value="datetime">datetime</option>
                            <option value="int">int</option>
                            <option value="file">file</option>
                            <option value="picture">picture</option>
                             <option value="password">password</option>
                        </optgroup>
                        <optgroup LABEL="Справочники">
                            <?php
                            reset($shemeEnums);
                            foreach($shemeEnums as $e)
                            {
                                $ename = $e->name;
                                $edescription = $e->description;
                                ?><option value="<?php echo $ename; ?>"><?php echo $edescription; ?></option><?php
                            }
                            ?>
                            </select>
                        </optgroup>
                        </td>
                        <tr><td>Размер:<td><input name="entity_field_modified[size]" size="6" value=""></td>
                        <tr><td>Справка:<td><input name="entity_field_modified[help]" size="32" value=""></td>
                        <tr><td>Скрытый:<td><input name="entity_field_modified[hidden]" type="checkbox" value=""></td>
                        <tr><td>Индексируемое:<td><input name="entity_field_modified[forsearch]" type="checkbox" value=""></td>
                        <!-- tr><td>&nbsp;<td><input name="entity_field_modified[entity_field_modified]" type="submit" value="Сохранить"></td -->
                        </a>
                        </td></tr></table>
                    </blockquote>
                </form>

            </td>
            </tr></table>
<?php } ?>

</div>

<?php $mikron->Page->EndBody(); ?>